﻿//什么是线程安全问题？
//线程安全问题主要出现在多线程编程中，当多个线程同时访问和修改同一块内存区域（如全局变量、静态变量、堆内存等）时，如果没有适当的同步控制，可能会导致数据的不一致性或者其他未预期的结果，这就是线程安全问题。

//举个简单的例子，假设有两个线程同时对一个整数变量进行加1操作，理论上执行完两个线程后，这个整数应该增加2，但实际上可能只增加了1。因为两个线程可能同时读取到变量的原始值，然后各自增加1后写回，结果就只增加了1，而不是预期的2，这就是一个典型的线程安全问题。

//为了解决线程安全问题，通常需要使用一些同步机制，如互斥锁（Mutex）、信号量（Semaphore）、读写锁（ReadWriteLock）等，来确保在任意时刻，只有一个线程能够访问和修改共享数据，从而保证数据的一致性

//such as
using System.Collections.Concurrent;

int obj = 0;

//创建一个锁对象
//Object lockOject = new object();

List<Task> tasks = new List<Task>();

//tasks.Add(Task.Run(() =>
//{
//    int i = 1;
//    while (i <= 10000000)
//    {
//        i++;
//        lock (lockOject)
//        {
//            obj++;
//        }
//    }
//}));
//tasks.Add(Task.Run(() =>
//{
//    int i = 1;
//    while (i <= 10000000)
//    {
//        i++;
//        lock (lockOject)
//        {
//            obj++;
//        }
//    }
//}));

//针对线程安全问题的一种处理方式便是使用lock

//然而，在很多对性能有很高要求的场景中（例如tob类型项目的高并发场景）使用锁会严重降低性能，这是无法接受的,因此另一种处理方式是使用线程安全版本的类型

//如果使用Dictionary，在多线程环境下会直接报错，因为
//Dictionary<TKey, TValue> 不是线程安全的，这意味着如果你在没有适当同步的情况下从多个线程访问它，就可能会遇到问题。在这个例子中，看起来你正在尝试从多个线程同时添加元素到字典，这导致了冲突和数据损坏。
//因此，此处只能使用
ConcurrentDictionary<string, int> dic = new();

tasks.Add(Task.Run(() =>
{
    int i = 1;
    while (i <= 10000000)
    {
        i++;
        dic.TryAdd(i + "a", i);
    }
}));
tasks.Add(Task.Run(() =>
{
    int i = 1;
    while (i <= 10000000)
    {
        i++;
        dic.TryAdd(i + "b", i);
    }
}));

await Task.WhenAll(tasks);

//Thread thread1 = new Thread(() =>
//{
//    int i = 1;
//    while (i <= 10000)
//    {
//        i++;
//        obj++;
//    }
//});

//Thread thread2 = new Thread(() =>
//{
//    int i = 1;
//    while (i <= 10000)
//    {
//        i++;
//        obj++;
//    }
//});

//thread1.Start();
//thread2.Start();

//thread1.Join();
//thread2.Join();

//Console.WriteLine(obj);
Console.WriteLine(dic.Count);